package com.example.order.controller;

import com.example.feign.bo.Person01BO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * /rest/selcet/1：当restTemplate的Bean上不配@LoadBalanced，则直接使用ip+port调用
 * /rest/test/1：若想使用服务名如userservice，则需要加此注解
 */
@RestController
@RequestMapping(value = "/rest")
@ResponseBody
public class RestTemplateController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    //rest/selcet/1：当restTemplate的Bean上不配@LoadBalanced，则直接使用ip+port调用
    @GetMapping("/select/{id}")
    public String select(@PathVariable("id")String id) {
        System.out.println("get into RestTemplateController /rest/select/{id}...");
        //动态从Eureka Server 中获取 provider 的 ip 和端口  注入 DiscoveryClient 对象.激活
        List<ServiceInstance> instances = discoveryClient.getInstances("userservice");
        //判断集合是否有数据
        if(instances == null || instances.size() == 0) {
            System.out.println("未获取到实例");
            return "未获取到实例";
        }
        ServiceInstance instance = instances.get(0);
        String host = instance.getHost();//获取ip
        int port = instance.getPort();//获取端口
        System.out.println("instance url is :"+host+":"+port);
        String url1 = "http://"+host+":"+port+"/user/select/"+id;
        String url2="http://userservice/user/select/"+id;
        System.out.println("url1:"+url1);
        System.out.println("url2:"+url2);
        // 3. 调用方法
        ArrayList forObject = restTemplate.getForObject(url2, ArrayList.class);
        System.out.println(forObject.get(0));
        return forObject.get(0).toString();
    }

    //rest/test/1：若想使用服务名如userservice，则需要加此注解@LoadBalance
    @RequestMapping(value = "/test/{id}",method = RequestMethod.GET)
    public void getAllPerson01BO(@PathVariable("id")String id) throws JsonProcessingException {
        System.out.println("api : /rest/test");
        ArrayList forObject = restTemplate.getForObject("http://userservice/user/select/"+id, ArrayList.class);

        //上面是调用范例，下面是序列化成LinkedHashMap的问题
        if(forObject==null||forObject.size()==0){
            System.out.println("结果为空");
        }else {
            Object o = forObject.get(0);
            System.out.print("if instanceof of Person01");
            System.out.println(o instanceof Person01BO);//false
            System.out.print("if instanceof of LinkedHashMap");
            System.out.println(o instanceof LinkedHashMap);//true ArrayList<LinkedHashMap>

        /*因为rpc远程调用在底层还是使用的HTTPClient，所以在传递参数的时候，必定要有个顺序，
        当你传递map的时候map里面的值也要有顺序，不然服务层在接的时候就出问题了，所以它才会从map转为linkedhashMap！
        spring 有一个类叫ModelMap，继承了linkedhashMap public class ModelMap extends LinkedHashMap,
        所以一个接口返回的结果就可以直接用ModelMap来接，注意ModelMap是没有泛型的，
        不管你返回的结果是什么类型的map，泛型是多复杂的map，都可以直接new一个Modelmap，用它来接返回的结果！
        如果用Feign调用则可以省略这部反序列化过程。
        */
            ObjectMapper objectMapper = new ObjectMapper();
            Person01BO person01BO = objectMapper.convertValue(o, Person01BO.class);
            System.out.println(person01BO);
        }
    }

}

